package org.example.fancystudy.CompletableFuture;

import lombok.*;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * @author chaigq
 * @version 1.0
 * @date 2022/11/7 11:15
 */
public class CompletableFutureDemo {
    public static List<Mall> list = Arrays.asList(
            new Mall("JD"),
            new Mall("TM"),
            new Mall("PDD"),
            new Mall("TB")
    );

    /**
     * List<NetMall> ----->map------> List<String>
     * @param list
     * @param productName
     * @return
     */
    public static List<String> getPrice(List<Mall> list,String productName){
        // 格式 《mysql》 in taobao price is 90.43
        return list
                .stream()
                .map(mall ->
                    String.format(productName+" in %s price is %.2f",
                            mall.getMallName(),
                            mall.calcPrice(productName))
        ).collect(Collectors.toList());
    }

    /**
     * List<NetMall> ----->List<CompletableFuture<String>>------> List<String>
     * @param list
     * @param productName
     * @return
     */
    public static List<String> getPriceByCompletableFuture(List<Mall> list,String productName){
        return list.stream().map(
                mall -> CompletableFuture.supplyAsync(() -> String.format(productName+" in %s price is %.2f",
                        mall.getMallName(),
                        mall.calcPrice(productName)))
        ).collect(Collectors.toList())
                .stream()
                .map(s ->
                        s.join()
                ).collect(Collectors.toList());
    }

//    public static void main(String[] args) {
//        long startTime = System.currentTimeMillis();
//        List<String> list1 = getPrice(list, "mysql");
//        for (String element : list1) {
//            System.out.println(element);
//        }
//        long endTime = System.currentTimeMillis();
//        System.out.println("----costTime: "+(endTime - startTime) +" 毫秒");
//        System.out.println("--------------------");
//        long startTime2 = System.currentTimeMillis();
//        List<String> list2 = getPriceByCompletableFuture(list, "mysql");
//        for (String element : list2) {
//            System.out.println(element);
//        }
//        long endTime2 = System.currentTimeMillis();
//        System.out.println("----costTime: "+(endTime2 - startTime2) +" 毫秒");
//    }

    public static void main(String[] args){
        ExecutorService threadPool = Executors.newFixedThreadPool(3);

        CompletableFuture.supplyAsync(() ->{
            //暂停几秒钟线程
            try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
            System.out.println("111");
            return 1;
        },threadPool).thenApply(f -> {
            System.out.println("222");
            return f + 2;
        }).thenApply(f -> {
            System.out.println("333");
            return f + 3;
        }).whenComplete((v,e) -> {
            if (e == null) {
                System.out.println("----计算结果： "+v);
            }
        }).exceptionally(e -> {
            e.printStackTrace();
            System.out.println(e.getMessage());
            return null;
        });

        System.out.println(Thread.currentThread().getName()+"----主线程先去忙其它任务");

        threadPool.shutdown();
    }


}
class Mall{
    @Getter
    private String mallName;

    public Mall(String mallName)
    {
        this.mallName = mallName;
    }

    public double calcPrice(String productName)
    {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return ThreadLocalRandom.current().nextDouble() * 2 + productName.charAt(0);
    }
}
